home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / lib / time / strftime.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  4KB  |  164 lines

  1.  
  2. /*
  3.  *  STRFTIME.C
  4.  *
  5.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  6.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  7.  *    DICE-LICENSE.TXT.
  8.  */
  9.  
  10. #include <time.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13.  
  14. static char *AbMonth[12] = { "Jan","Feb","Mar","Apr","May","Jun","Jul",
  15.                  "Aug","Sep","Oct","Nov","Dec"
  16.                 };
  17.  
  18. static char *FuMonth[12] = { "January", "February", "March", "April", "May",
  19.                  "June", "July", "August", "September", "October",
  20.                  "November", "December"
  21.                 };
  22.  
  23. static char *AbDow[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
  24.  
  25. static char *FuDow[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
  26.                "Friday", "Saturday"
  27.             };
  28.  
  29.  
  30. size_t
  31. strftime(buf, max, fmt, tm)
  32. char *buf;
  33. size_t max;
  34. const char *fmt;
  35. const struct tm *tm;
  36. {
  37.     short i = 0;
  38.     char tmp[64];
  39.  
  40.     while (*fmt && max >= 0) {
  41.     if (max <= 0) {         /*  buffer overflow */
  42.         buf[i] = 0;
  43.         return(0);
  44.     }
  45.  
  46.     if (*fmt != '%') {
  47.         buf[i++] = *fmt++;
  48.         --max;
  49.         continue;
  50.     }
  51.  
  52.     fmt += 2;
  53.  
  54.     switch(fmt[-1]) {
  55.     case '%':
  56.         strcpy(tmp, "%");
  57.         break;
  58.     case 'a':   /*  abbreviated name for dow    */
  59.         strcpy(tmp, AbDow[tm->tm_wday]);
  60.         break;
  61.     case 'A':   /*  full name for dow           */
  62.         strcpy(tmp, FuDow[tm->tm_wday]);
  63.         break;
  64.     case 'b':   /*  abbreviated name for month  */
  65.         strcpy(tmp, AbMonth[tm->tm_mon]);
  66.         break;
  67.     case 'B':   /*  full name for month         */
  68.         strcpy(tmp, FuMonth[tm->tm_mon]);
  69.         break;
  70.     case 'c':   /*  default rep for date & time */
  71.         sprintf(tmp, "%s %s %02d %02d:%02d:%02d %d",
  72.         AbDow[tm->tm_wday], AbMonth[tm->tm_mon], tm->tm_mday,
  73.         tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_year + 1900
  74.         );
  75.         break;
  76.     case 'd':   /*  day of month as integer 01-31   */
  77.         sprintf(tmp, "%02d", tm->tm_mday);
  78.         break;
  79.     case 'H':   /*  hour as integer 00-23       */
  80.         sprintf(tmp, "%02d", tm->tm_hour);
  81.         break;
  82.     case 'I':   /*  hour as integer 01-12       */
  83.         {
  84.         short hr = (tm->tm_hour % 12);
  85.         sprintf(tmp, "%02d", (hr) ? hr : 12);
  86.         }
  87.         break;
  88.     case 'j':   /*  day of year as int 001-366  */
  89.         sprintf(tmp, "%03d", tm->tm_yday + 1);
  90.         break;
  91.     case 'm':   /*  month as integer 01-12      */
  92.         sprintf(tmp, "%02d", tm->tm_mon + 1);
  93.         break;
  94.     case 'M':   /*  minute as integer 00-59     */
  95.         sprintf(tmp, "%02d", tm->tm_min);
  96.         break;
  97.     case 'p':   /*  'AM' or 'PM'                */
  98.         if (tm->tm_hour >= 12) {
  99.         strcpy(tmp, "PM");
  100.         } else {
  101.         strcpy(tmp, "AM");
  102.         }
  103.         break;
  104.     case 'S':   /*  the second as an int 00-59  */
  105.         sprintf(tmp, "%02d", tm->tm_sec);
  106.         break;
  107.     case 'U':   /*  week of year as int 00-53, regard sunday as first day in week   */
  108.     case 'W':   /*  week of year as int 00-53, regard monday as first day in week   */
  109.         {
  110.         int fdiy = tm->tm_yday % 7 - tm->tm_wday;    /*  first sunday in year, can be negative */
  111.         if (fmt[-1] == 'W')
  112.             ++fdiy;                    /*  first monday in year, can be negative */
  113.  
  114.         while (fdiy > 0)                                /*  handle boundry cases                  */
  115.             fdiy -= 7;
  116.         while (fdiy <= -7)
  117.             fdiy += 7;
  118.  
  119.         sprintf(tmp, "%02d", (tm->tm_yday - fdiy) / 7);
  120.         }
  121.         break;
  122.     case 'w':   /*  day of week as int 0-6, sunday == 0 */
  123.         sprintf(tmp, "%d", tm->tm_wday);
  124.         break;
  125.     case 'x':   /*  the locale's default rep for date   */
  126.         sprintf(tmp, "%s %s %02d",
  127.         AbDow[tm->tm_wday], AbMonth[tm->tm_mon], tm->tm_mday
  128.         );
  129.         break;
  130.     case 'X':   /*  the locale's default rep for time   */
  131.         sprintf(tmp, "%02d:%02d:%02d",
  132.         tm->tm_hour, tm->tm_min, tm->tm_sec
  133.         );
  134.         break;
  135.     case 'y':   /*  year within the century 00-99       */
  136.         sprintf(tmp, "%02d", tm->tm_year % 100);
  137.         break;
  138.     case 'Y':   /*  the full year, including century    */
  139.         sprintf(tmp, "%04d", tm->tm_year + 1900);
  140.         break;
  141.     case 'Z':   /*  the name of the time zone or ""     */
  142.         strcpy(tmp, "");
  143.         break;
  144.     default:
  145.         strcpy(tmp, "%?");
  146.         break;
  147.     }
  148.     {
  149.         short len = strlen(tmp);
  150.  
  151.         max -= len;
  152.         if (max < 0) {
  153.         buf[i] = 0;
  154.         return(0);
  155.         }
  156.         strcpy(buf + i, tmp);
  157.         i += len;
  158.     }
  159.     }
  160.     buf[i] = 0;
  161.     return(i);
  162. }
  163.  
  164.